package com.bn.commerce.order.purchase;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.transaction.Transaction;

import com.bn.commerce.order.BNCreditCard;
import com.bn.commerce.order.BNCreditCardTools;
import com.bn.commerce.order.BNOrderImpl;
import com.bn.userprofile.BNProfileTools;
import com.bn.util.BNContactInfo;
import com.bn.util.BNRepositoryContactInfo;

import atg.commerce.CommerceException;
import atg.commerce.order.CreditCard;
import atg.commerce.order.DuplicatePaymentGroupException;
import atg.commerce.order.HardgoodShippingGroup;
import atg.commerce.order.InvalidParameterException;
import atg.commerce.order.OrderTools;
import atg.commerce.order.PaymentGroup;
import atg.commerce.order.ShippingGroup;
import atg.commerce.util.RepeatingRequestMonitor;
import atg.core.util.Address;
import atg.projects.store.order.purchase.BillingInfoFormHandler;
import atg.projects.store.profile.StorePropertyManager;
import atg.servlet.DynamoHttpServletRequest;
import atg.servlet.DynamoHttpServletResponse;

public class BNBillingInfoFormHandler extends BillingInfoFormHandler{

	private BNContactInfo billingContactInfo;
	private String billingInfoSuccessURL;
	private String billingInfoErrorURL;
	private boolean sameAsShipping;
	private BNProfileTools bnProfileTools;
	private Address shippingAddress;
	private String nameOnCard;
	private BNCreditCard creditCardPaymentGroup;

	public boolean handleBillingInfo(
			DynamoHttpServletRequest pRequest,
			DynamoHttpServletResponse pResponse) throws ServletException,
			IOException, CommerceException {

		RepeatingRequestMonitor rrm = getRepeatingRequestMonitor();
		String myHandleMethod = "BNBillingInfoFormHandler.handleAddItemToOrder";
		if ((rrm == null) || (rrm.isUniqueRequestEntry(myHandleMethod))) {

			Transaction tr = null;
			try{
				tr = ensureTransaction();

				synchronized (getOrder()) {
					createBillingInfo();
					BNCreditCard creditCard = createCreditCard();
				}
			}catch(Exception e){

			}
		}
		return checkFormRedirect(getBillingInfoSuccessURL(),
				getBillingInfoErrorURL(), pRequest, pResponse);
	}

	protected BNCreditCard createCreditCard()
			throws DuplicatePaymentGroupException, InvalidParameterException,
			CommerceException {

		StorePropertyManager propertyManager = (StorePropertyManager) getBnProfileTools()
				.getPropertyManager();

		BNCreditCard bnCreditCard = getCreditCardPaymentGroup();
		BNOrderImpl bnOrderImpl =(BNOrderImpl)getOrder();
		BNCreditCardTools bnCreditCardTools = (BNCreditCardTools)getCreditCardTools();
		if (bnCreditCard == null)
			return null;
		String cardNumber = null;
		String cardType = null;
		String cardExpirationMonth = null;
		String cardExpirationYear = null;
		String nameOnCard = null;

		// If card details entered manually
		cardNumber = getCreditCardNumber();
		cardType = bnCreditCardTools.getCreditCardType(cardNumber);
		cardExpirationMonth = getCreditCardExpirationMonth();
		cardExpirationYear = getCreditCardExpirationYear();
		nameOnCard = getNameOnCard();

		if (cardNumber != null) {
			cardNumber = cardNumber.replaceAll(" ", "");
			cardNumber = cardNumber.replaceAll("-", "");
			cardNumber = cardNumber.trim();
		}

		bnCreditCard.setCreditCardNumber(cardNumber);
		bnCreditCard.setCreditCardType(cardType);
		bnCreditCard.setExpirationMonth(cardExpirationMonth);
		bnCreditCard.setExpirationYear(cardExpirationYear);
		bnCreditCard.setNameOnCard(nameOnCard);
		return bnCreditCard;

	}

	public BNCreditCard getCreditCardPaymentGroup()
			throws DuplicatePaymentGroupException, InvalidParameterException,
			CommerceException {

		if (this.creditCardPaymentGroup == null) {
			List<PaymentGroup> paymentGroups = getOrder().getPaymentGroups();
			if (paymentGroups != null && paymentGroups.size() > 0) {
				for (PaymentGroup paymentGroup : paymentGroups) {
					if (paymentGroup instanceof CreditCard) {
						this.creditCardPaymentGroup = (BNCreditCard) paymentGroup;
						break;
					}
				}
			}
		}

		if (this.creditCardPaymentGroup == null) {
			Transaction tr = null;
			try {
				tr = ensureTransaction();

				this.creditCardPaymentGroup = (BNCreditCard) createCCPaymentGroup();

				getOrderManager().updateOrder(getOrder());

			}catch(Exception e){

			}
			finally{
				commitTransaction(tr);
			}
		}

		return this.creditCardPaymentGroup;
	}

	protected PaymentGroup createCCPaymentGroup() throws CommerceException {

		PaymentGroup pg = getPaymentGroupManager().createPaymentGroup();
		getOrder().addPaymentGroup(pg);

		return pg;
	}

	/**
	 * Creates Billing ContactInfo object
	 *
	 * @throws CommerceException
	 */
	protected void createBillingInfo() throws CommerceException {
		if (isSameAsShipping()) {
			BNRepositoryContactInfo shipContactInfo = (BNRepositoryContactInfo) getHardgoodShippingGroup().getShippingAddress();
			OrderTools.copyAddress(shipContactInfo, billingContactInfo);
			setBillingContactInfo(billingContactInfo);
		}
		String email = getBillingContactInfo().getEmail();
		BNOrderImpl orderImpl = (BNOrderImpl)getOrder();
		orderImpl.setBillingSameAsShipping(isSameAsShipping());
		getBillingContactInfo().setEmail(email);
	}

	protected HardgoodShippingGroup getHardgoodShippingGroup() {

		HardgoodShippingGroup hsg = null;
		List<ShippingGroup> shippingGroups = getOrder().getShippingGroups();
		if (shippingGroups != null && shippingGroups.size() > 0) {
			for (ShippingGroup sg : shippingGroups) {
				if (sg instanceof HardgoodShippingGroup) {
					hsg = (HardgoodShippingGroup) sg;
					break;
				}
			}
		}
		return hsg;
	}




	public BNContactInfo getBillingContactInfo() {
		if(billingContactInfo == null){
			billingContactInfo = new BNContactInfo();
		}
		return billingContactInfo;
	}

	public void setBillingContactInfo(BNContactInfo billingContactInfo) {
		this.billingContactInfo = billingContactInfo;
	}

	public String getBillingInfoSuccessURL() {
		return billingInfoSuccessURL;
	}

	public void setBillingInfoSuccessURL(String billingInfoSuccessURL) {
		this.billingInfoSuccessURL = billingInfoSuccessURL;
	}

	public String getBillingInfoErrorURL() {
		return billingInfoErrorURL;
	}

	public void setBillingInfoErrorURL(String billingInfoErrorURL) {
		this.billingInfoErrorURL = billingInfoErrorURL;
	}


	public boolean isSameAsShipping() {
		return sameAsShipping;
	}


	public void setSameAsShipping(boolean sameAsShipping) {
		this.sameAsShipping = sameAsShipping;
	}


	public BNProfileTools getBnProfileTools() {
		return bnProfileTools;
	}


	public void setBnProfileTools(BNProfileTools bnProfileTools) {
		this.bnProfileTools = bnProfileTools;
	}


	public Address getShippingAddress() {
		return shippingAddress;
	}


	public void setShippingAddress(Address shippingAddress) {
		this.shippingAddress = shippingAddress;
	}

	public String getNameOnCard() {
		return nameOnCard;
	}

	public void setNameOnCard(String nameOnCard) {
		this.nameOnCard = nameOnCard;
	}
}
